import re

import allure
import pytest

from utils.util_logger import logger
from utils.util_assert import UtilAssert
from utils.util_extract_response_data import UtilExtractData
from utils.util_yaml_file import YamlUtil


class UtilExcuteCase:
    """
        用例执行工具
    """

    @classmethod
    def excute_testcase(cls, test_data: dict, session_request_class):
        """测试用例执行方法"""
        if not session_request_class.headers.get("Authorization", None):
            logger.error("会话中缺失Authorization头")
            pytest.fail("会话未正确初始化认证头")

        with allure.step("1. 获取接口数据"):
            case_name = test_data.get("case_name")
            allure.dynamic.title(case_name)
            logger.debug(f"接口名称: {case_name}")

            request_data = test_data.get("request")
            logger.debug(f"接口请求参数: {request_data}")

            validation_data = test_data.get("validation")
            # validation_data = cls.replace_field(validation_data)
            logger.debug(f"接口断言信息: {validation_data}")

            extract_data = test_data.get("extract")
            if extract_data:
                extract_data = test_data.get("extract")
                logger.debug(f"接口提取信息: {extract_data}")

        with allure.step("2. 发送接口请求"):
            response = session_request_class.send_api(
                method=request_data.get("method", None),
                url=request_data.get("url", None),
                data=request_data.get("data", None),
                json=request_data.get("json", None)
            )
        logger.info(f"发送请求成功: {response.json()}")

        with allure.step("3. 断言接口"):
            for k, v in validation_data.items():
                if k == "status_code":
                    UtilAssert.assert_status_code(response, v)
                elif k == "eq":
                    UtilAssert.assert_eq(response, v)
                elif k == "exist":
                    UtilAssert.assert_exists(response, v)
                elif k == "schema":
                    UtilAssert.assert_schema_response_model(response, v)
        logger.info(f"断言成功")

        # 判断是否需要提取数据
        if extract_data:
            with allure.step("4. 提取数据"):
                UtilExtractData.save_response_data(response, extract_data, db_class=session_request_class)

    